package com.chushouya.common.applet;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.FileItem;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipayEncrypt;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.chushouya.common.constant.IdentityTypeEnum;
import com.chushouya.common.support.DevOption;
import com.chushouya.common.tool.Base64Util;
import com.general.framework.core.exception.Ex;
import com.general.framework.core.lang.Dates;
import com.general.framework.core.lang.Jsons;
import com.general.framework.core.lang.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.ArrayList;

import static com.chushouya.common.constant.AlipayConstants.FUND_TRUSTSHIP;
import static com.chushouya.common.constant.AlipayConstants.STANDARD_SCENE_WALLET;


public class AlipayClient {

    private final Logger log = LoggerFactory.getLogger(AlipayClient.class);
    private final String publicKey;
    private final String privateKey;
    private final String appCertPath;
    private final String alipayCertPath;
    private final String alipayRootCertPath;
    private final String signType = "RSA2";
    private final String decryptKey;
    private static final String FORMAT = "json";
    private static final String CHARSET = "UTF-8";
    private static final String serverUrl = "https://openapi.alipay.com/gateway.do";
//    private static final String serverUrl = "https://openapipre.alipay.com/gateway.do";
    private final com.alipay.api.AlipayClient alipayClient;

    /**
     * 通知地址
     */
    private final String notifyUrl = "https://api.chushouya.com/suhuishou-order/open-api/alipayGateway/notify";
    private final String testNotifyUrl = "https://test-api.chushouya.com/suhuishou-order/open-api/alipayGateway/notify";

    /**
     * 速回收常量
     */
    private static final String SUHUISHOU = "速回收";

    /**
     * 公私钥模式客户端
     */
    public AlipayClient(String appid, String privateKey, String publicKey, String secret) {
        this.publicKey = publicKey;
        this.privateKey = privateKey;
        this.decryptKey = secret;
        this.appCertPath = "";
        this.alipayCertPath = "";
        this.alipayRootCertPath = "";


        alipayClient = new DefaultAlipayClient(serverUrl, appid, privateKey, FORMAT, CHARSET, publicKey, signType);
    }

    /**
     * 证书模式客户端
     */
    public AlipayClient(String appid, String privateKey, String secret) {

        this.publicKey = "";
        this.privateKey = privateKey;
        this.decryptKey = secret;
        this.appCertPath = Strings.format("/data/cert/alipay/{}/appCertPublicKey_{}.crt", appid, appid);
        this.alipayCertPath = Strings.format("/data/cert/alipay/{}/alipayCertPublicKey_RSA2.crt", appid);
        this.alipayRootCertPath = Strings.format("/data/cert/alipay/{}/alipayRootCert.crt", appid);
        
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl(serverUrl);
        alipayConfig.setAppId(appid);
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat(FORMAT);
        alipayConfig.setCharset(CHARSET);
        alipayConfig.setSignType(signType);
        alipayConfig.setAppCertPath(appCertPath);
        alipayConfig.setAlipayPublicCertPath(alipayCertPath);
        alipayConfig.setRootCertPath(alipayRootCertPath);
        // 开发环境下使用沙箱网关
        if (appid.startsWith("9021000")) {
            alipayConfig.setServerUrl("https://openapi-sandbox.dl.alipaydev.com/gateway.do");
        }
        try {
            alipayClient = new DefaultAlipayClient(alipayConfig);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 支付宝小程序授权登录
     */
    public String jscode2session(String code) {

        if (Strings.isEmpty(code)) {
            throw Ex.business("code不能为空");
        }

        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");
        request.setCode(code);
        AlipaySystemOauthTokenResponse response;

        try {
            response = alipayClient.execute(request);
            if (!response.isSuccess()) {
                throw Ex.business(response.getMsg());
            }
            return response.getUserId();
        } catch (AlipayApiException e) {
            log.error("支付宝授权登录异常", e);
            throw Ex.business(e.getMessage(), e);
        }
    }

    /**
     * 支付宝获取手机号码
     *
     * @param response 支付宝授权后得到的response
     * @return 手机号码
     */
    public String getPhoneNumber(String response) {

        if (Strings.isEmpty(response)) {
            throw Ex.business("response不能为空");
        }

        // 1. 获取验签和解密所需要的参数
        Map<String, String> openapiResult = JSON.parseObject(response, new TypeReference<Map<String, String>>() {
        }, Feature.OrderedField);
        String encryptType = "AES";
        String sign = openapiResult.get("sign");
        String content = openapiResult.get("response");

        // 判断是否为加密内容
        boolean isDataEncrypted = !content.startsWith("{");
        boolean signCheckPass;

        // 2. 验签
        String signContent = content;
        // 如果是加密的报文则需要在密文的前后添加双引号
        if (isDataEncrypted) {
            signContent = "\"" + signContent + "\"";
        }

        try {
            if (Strings.isNotBlank(this.publicKey)) {
                signCheckPass = AlipaySignature.rsaCheck(signContent, sign, publicKey, CHARSET, signType);
            } else {
                signCheckPass = AlipaySignature.rsaCertCheck(signContent, sign, alipayCertPath, CHARSET, signType);
            }
        } catch (AlipayApiException e) {
            // 验签异常, 日志
            log.error("支付宝获取手机号码验签异常", e);
            throw Ex.business("验签异常");
        }

        if (!signCheckPass) {
            //验签不通过（异常或者报文被篡改），终止流程（不需要做解密）
            throw Ex.business("验签不通过");
        }

        // 3. 解密
        String decryptKey = this.decryptKey; // 小程序对应的 AES 密钥
        String plainData;
        if (isDataEncrypted) {
            try {
                plainData = AlipayEncrypt.decryptContent(content, encryptType, decryptKey, CHARSET);
            } catch (AlipayApiException e) {
                //解密异常, 记录日志
                log.error("支付宝获取手机号码解密异常", e);
                throw Ex.business("解密异常");
            }
        } else {
            plainData = content;
        }

        String mobile = JSON.parseObject(plainData).getString("mobile");
        if (Strings.isBlank(mobile)) {
            log.error("支付宝获取手机号码异常: {}", plainData);
            throw Ex.business("获取手机号码异常");
        }
        return mobile;
    }


    /**
     * 支付宝rsa签名
     *
     * @param content 待签名内容
     * @return 签名字符串
     */
    public String rsaSign(String content) {
        try {
            return AlipaySignature.rsaSign(content, privateKey, CHARSET, signType);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 钱包支付
     */
    public AlipayFundTransUniTransferResponse walletFundTransUniTransfer(String outBizNo, String transAmount, String orderTitle, String remark, String identity, String identityType, String name) {
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        request.setNotifyUrl(notifyUrl);
        AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
        model.setOutBizNo(outBizNo);
        model.setTransAmount(transAmount);
        model.setBizScene("DIRECT_TRANSFER");
        model.setOrderTitle(orderTitle);
        model.setRemark(remark);
        Participant participant = new Participant();
        participant.setIdentity(identity);
        participant.setIdentityType(identityType);
        model.setProductCode("SINGLE_TRANSFER_NO_PWD");
        model.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}");
        model.setPayeeInfo(participant);
        request.setBizModel(model);
        log.info("支付宝转账请求参数, outBizNo: {}, request: {}", outBizNo, Jsons.toJsonString(request));
        AlipayFundTransUniTransferResponse response = null;
        try {
            response = alipayClient.certificateExecute(request);
            log.info("支付宝转账结果, outBizNo: {}, response: {}", outBizNo, Jsons.toJsonString(response));

            if (!response.isSuccess()) {
                log.error("支付宝转账失败, outBizNo: {}, 姓名: {}, 账号: {} {}", outBizNo, name, identity, response.getSubMsg());
//                throw Ex.business("支付宝转账异常, " + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            log.error("支付宝转账接口异常, outBizNo: {}, e: {}", outBizNo, e);
//            throw Ex.business("支付宝转账接口异常", e);
        }
        log.info("支付宝转账结果, outBizNo: {}, response: {}", outBizNo, Jsons.toJsonString(response));
        return response;
    }

    /**
     * 转账
     *
     * @param outBizNo     转账单号
     * @param transAmount  转账金额
     * @param orderTitle   转账业务标题
     * @param identity     转账参与方标识ID
     * @param identityType 转账参与方标识类型
     * @param name         参与方真实姓名 identityType = ALIPAY_LOGON_ID时必填
     */
    public AlipayFundTransUniTransferResponse fundTransUniTransfer(String outBizNo, String transAmount, String orderTitle, String remark, String identity, String identityType, String name) {
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        request.setNotifyUrl(notifyUrl);
        AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
        model.setOutBizNo(outBizNo);
        model.setTransAmount(transAmount);
        model.setBizScene("DIRECT_TRANSFER");
        model.setOrderTitle(orderTitle);
        model.setRemark(remark);
        Participant participant = new Participant();
        participant.setIdentity(identity);
        participant.setIdentityType(identityType);
        if (Objects.equals(identityType, IdentityTypeEnum.ALIPAY_LOGON_ID.name())) {
            participant.setName(name);
            model.setProductCode("TRANS_ACCOUNT_NO_PWD");
        } else if (Objects.equals(identityType, IdentityTypeEnum.ALIPAY_USER_ID.name())) {
            model.setProductCode("TRANS_ACCOUNT_NO_PWD");
        }
        model.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}");
        model.setPayeeInfo(participant);
        request.setBizModel(model);
        log.info("支付宝转账请求参数, outBizNo: {}, request: {}", outBizNo, Jsons.toJsonString(request));
        AlipayFundTransUniTransferResponse response = null;
        try {
            response = alipayClient.certificateExecute(request);
            log.info("支付宝转账结果, outBizNo: {}, response: {}", outBizNo, Jsons.toJsonString(response));

            if (!response.isSuccess()) {
                log.error("支付宝转账失败, outBizNo: {}, 姓名: {}, 账号: {} {}", outBizNo, name, identity, response.getSubMsg());
//                throw Ex.business("支付宝转账异常, " + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            log.error("支付宝转账接口异常, outBizNo: {}, e: {}", outBizNo, e);
//            throw Ex.business("支付宝转账接口异常", e);
        }
        log.info("支付宝转账结果, outBizNo: {}, response: {}", outBizNo, Jsons.toJsonString(response));
        return response;
    }


    /**
     * alipay.trade.wap.pay(手机网站支付接口2.0)
     */
    public String alipayTradeWapPay(String orderNo, String totalAmount, String subject, String notifyUrl, String returnUrl) {
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(orderNo);
        model.setTotalAmount(totalAmount);
        model.setSubject(subject);
        model.setProductCode("QUICK_WAP_WAY");
        model.setTimeoutExpress("30m");
        request.setBizModel(model);
        request.setNotifyUrl(notifyUrl);
        request.setReturnUrl(returnUrl);
        try {
            AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "GET");
            log.info("商户创建支付宝结果:{}", JSON.toJSONString(response));
            if (!response.isSuccess()) {
                throw Ex.business("商户商户创建支付宝异常:" + response.getSubMsg());
            }

            return response.getBody();
        } catch (AlipayApiException e) {
            throw Ex.business("商户商户创建支付宝异常:" + e.getMessage());
        }
    }

    /**
     * 修改模板
     */
    public void alipayFundWalletTemplateModify(String walletTemplateId, String walletTemplateName) {
//        AlipayFundWalletTemplateModifyRequest request = new AlipayFundWalletTemplateModifyRequest();
//        AlipayFundWalletTemplateModifyModel model = new AlipayFundWalletTemplateModifyModel();
//        model.setBizScene(STANDARD_SCENE_WALLET);
//        model.setProductCode(FUND_TRUSTSHIP);
//        model.setWalletTemplateId(walletTemplateId);
//        model.setWalletTemplateName(walletTemplateName);
//        request.setBizModel(model);
//        log.info("修改钱包模版请求参数：{}", JSON.toJSONString(request));
//        AlipayFundWalletTemplateModifyResponse response = null;
//        try {
//            if (Strings.isNotBlank(this.publicKey)) {
//                response = alipayClient.execute(request);
//            } else {
//                response = alipayClient.certificateExecute(request);
//            }
//            log.info("修改钱包模版结果:{}", Jsons.toFormatJsonString(response));
//            if (!response.isSuccess()) {
//                throw Ex.business("修改钱包模版异常:" + response.getSubMsg());
//            }
//        } catch (AlipayApiException e) {
//            log.error("修改钱包模版异常:{}", e.getMessage());
//            throw Ex.business("修改钱包模版异常:" + e.getMessage());
//        }
    }


    /**
     * 接口英文名称：alipay.fund.wallet.template.create 商户创建钱包模版
     * 请求url：https://openapi.alipay.com/v3/alipay/fund/wallet/template/create
     * 请求方式：POST
     */
    public void alipayFundWalletTemplateCreate(String outBizNo) {
        AlipayFundWalletTemplateCreateRequest request = new AlipayFundWalletTemplateCreateRequest();
        AlipayFundWalletTemplateCreateModel model = new AlipayFundWalletTemplateCreateModel();
        model.setBizScene(STANDARD_SCENE_WALLET);
        model.setProductCode(FUND_TRUSTSHIP);
        model.setWalletTemplateName("回收专用款");
        model.setOutBizNo(outBizNo);
        ConsumeExtend consumeExtend = new ConsumeExtend();
        consumeExtend.setRecycleIndustry(true);
        model.setConsumeExtend(consumeExtend);
        request.setBizModel(model);
        log.info("商户创建钱包模版请求参数：{}", JSON.toJSONString(request));
        AlipayFundWalletTemplateCreateResponse response = null;
        log.info("商户创建钱包模版请求参数：{}", this.publicKey);
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("商户创建钱包模版结果:{}", Jsons.toFormatJsonString(response));
            if (!response.isSuccess()) {
                throw Ex.business("商户创建钱包模版异常:" + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            log.error("商户创建钱包模版异常:{}", e.getMessage());
            throw Ex.business("商户创建钱包模版异常:" + e.getMessage());
        }
    }

    /**
     * 接口英文名称：alipay.fund.wallet.template.confirm 商户确认开通钱包
     * https://opendocs.alipay.com/pre-apis/05v8j4
     */
    public void alipayFundWalletTemplateConfirm() {
        AlipayFundWalletTemplateConfirmRequest request = new AlipayFundWalletTemplateConfirmRequest();
        AlipayFundWalletTemplateConfirmModel model = new AlipayFundWalletTemplateConfirmModel();
        model.setBizScene(STANDARD_SCENE_WALLET);
        model.setProductCode(FUND_TRUSTSHIP);
        model.setWalletTemplateName("深电资源回收钱包");
        request.setBizModel(model);
        AlipayFundWalletTemplateConfirmResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("商户确认开通钱包结果:{}", JSON.toJSONString(response));
            if (!response.isSuccess()) {
                throw Ex.business("商户确认开通钱包异常:" + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            log.error("商户确认开通钱包异常:{}", e.getMessage());
            throw Ex.business("商户确认开通钱包异常:" + e.getMessage());
        }
    }

    /**
     * 接口英文名称：alipay.fund.wallet.token.create 生成用户授权链接
     * https://opendocs.alipay.com/pre-apis/05ujp3
     */
    public AlipayFundWalletTokenCreateResponse alipayFundWalletTokenCreate(String outBizNo, String walletTemplateId,String identity) {
        AlipayFundWalletTokenCreateRequest request = new AlipayFundWalletTokenCreateRequest();
        AlipayFundWalletTokenCreateModel model = new AlipayFundWalletTokenCreateModel();
        model.setBizScene(STANDARD_SCENE_WALLET);
        model.setProductCode(FUND_TRUSTSHIP);
        model.setOutBizNo(outBizNo);
        model.setWalletTemplateId(walletTemplateId);
        model.setIdentityType("ALIPAY_USER_ID");
        model.setIdentity(identity);
        request.setBizModel(model);
        AlipayFundWalletTokenCreateResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("生成用户授权链接结果:{}", JSON.toJSONString(response));
            if (!response.isSuccess()) {
                throw Ex.business("生成用户授权链接异常:" + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business("生成用户授权链接异常:" + e.getMessage());
        }
        return response;
    }

    /**
     * 接口英文名称：alipay.fund.wallet.consult 查询用户钱包
     * https://opendocs.alipay.com/apis/05vekx?scene=8fca7f3743d945b196c37d86491a0d2d
     */
    public AlipayFundWalletConsultResponse alipayFundWalletConsult(String userWalletId) {
        AlipayFundWalletConsultRequest request = new AlipayFundWalletConsultRequest();
        AlipayFundWalletConsultModel model = new AlipayFundWalletConsultModel();
        model.setUserWalletId(userWalletId);
        model.setBizScene(STANDARD_SCENE_WALLET);
        model.setProductCode(FUND_TRUSTSHIP);
        model.setSearchType("WALLET_INFO");
        request.setBizModel(model);
        AlipayFundWalletConsultResponse response = null;
        log.info("查询用户钱包结果:{}", JSON.toJSONString(model));
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("查询用户钱包结果:{}", JSON.toJSONString(response));
            if (!response.isSuccess()) {
                throw Ex.business("查询用户钱包结果:" + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business("查询用户钱包结果:" + e.getMessage());
        }
        return response;
    }

    /**
     * ● 接口类型：openapi
     * ● 接口名称：alipay.fund.wallet.refund
     * ● 接口描述：钱包资金原路退
     * ● 接口功能：用户钱包资金原路退回到原充值账号
     * ● 接口链接：https://opendocs.alipay.com/apis/05uuie?scene=0ef549aefdc54231914041be97e736b2
     */
    public AlipayFundWalletRefundResponse alipayFundWalletRefund(String outBizNo, String amount, String userWalletId) {
        AlipayFundWalletRefundRequest request = new AlipayFundWalletRefundRequest();
        AlipayFundWalletRefundModel model = new AlipayFundWalletRefundModel();
        model.setOutBizNo(outBizNo);
        model.setAmount(amount);
        model.setUserWalletId(userWalletId);
        model.setBizScene(STANDARD_SCENE_WALLET);
        model.setProductCode(FUND_TRUSTSHIP);
        request.setBizModel(model);
        AlipayFundWalletRefundResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("钱包资金原路退结果:{}", JSON.toJSONString(response));
            if (!response.isSuccess()) {
                log.error("钱包资金原路退异常:{}", response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            log.error("钱包资金原路退异常:{}", e.getMessage());
        }
        return response;
    }

    /**
     * ● 接口类型：openapi
     * ● 接口名称：alipay.fund.wallet.withdraw
     * ● 接口描述：钱包资金提现到用户余额
     * ● 接口功能：用户钱包资金提现到用户余额
     * ● 接口链接：https://opendocs.alipay.com/apis/073gjs?scene=fe6e4f4f3aa14bb5afc2dd3860ba2ebe
     */
    public AlipayFundWalletWithdrawResponse alipayFundWalletWithdraw(String outBizNo, String amount, String userWalletId) {
        AlipayFundWalletWithdrawRequest request = new AlipayFundWalletWithdrawRequest();
        AlipayFundWalletWithdrawModel model = new AlipayFundWalletWithdrawModel();
        model.setOutBizNo(outBizNo);
        model.setAmount(amount);
        model.setOrderTitle("速回收专款回收款提现");
        model.setUserWalletId(userWalletId);
        model.setBizScene(STANDARD_SCENE_WALLET);
        model.setProductCode(FUND_TRUSTSHIP);
        request.setBizModel(model);
        AlipayFundWalletWithdrawResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("钱包资金提现到用户余额结果:{}", JSON.toJSONString(response));
            if (!response.isSuccess()) {
                throw Ex.business("生成用户授权链接异常:" + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business("生成用户授权链接异常:" + e.getMessage());
        }
        return response;
    }

    /**
     * * 接口英文名称：alipay.fund.wallet.destroy(场景钱包解约)
     * * 接口描述：场景钱包解约
     * * 接口功能：场景钱包解约
     *
     * @param userWalletId
     */

    public void alipayFundWalletDestroy(String userWalletId) {
        AlipayFundWalletDestroyRequest request = new AlipayFundWalletDestroyRequest();
        AlipayFundWalletDestroyModel model = new AlipayFundWalletDestroyModel();
        model.setUserWalletId(userWalletId);
        model.setProductCode(FUND_TRUSTSHIP);
        model.setBizScene(STANDARD_SCENE_WALLET);
        request.setBizModel(model);
        AlipayFundWalletDestroyResponse response;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            if (!response.isSuccess()) {
                throw Ex.business("生成用户授权链接异常:" + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business("生成用户授权链接异常:" + e.getMessage());
        }
    }


    /**
     * alipay.fund.wallet.order.query(场景钱包单据查询)
     */
    public void alipayFundWalletOrderQuery(String orderNo, String userWalletId) {
        AlipayFundWalletOrderQueryRequest request = new AlipayFundWalletOrderQueryRequest();
        AlipayFundWalletOrderQueryModel model = new AlipayFundWalletOrderQueryModel();
        model.setBizScene(STANDARD_SCENE_WALLET);
        model.setProductCode(FUND_TRUSTSHIP);
        model.setUserWalletId(userWalletId);
        model.setBillNo(orderNo);
        model.setBillType("WITHDRAW");
        request.setBizModel(model);
        AlipayFundWalletOrderQueryResponse response = null;
        try {
            response = alipayClient.certificateExecute(request);
            log.info("场景钱包单据查询结果:{}", JSON.toJSONString(response));
            if (!response.isSuccess()) {
                throw Ex.business("生成用户授权链接异常:" + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business("生成用户授权链接异常:" + e.getMessage());
        }
    }


    /**
     * 生成支付宝小程序二维码
     */
    public AlipayOpenAppQrcodeCreateResponse alipayOpenAppQrcodeCreate(String urlParam, String queryParam, String size, String describe) {
        AlipayOpenAppQrcodeCreateRequest request = new AlipayOpenAppQrcodeCreateRequest();
        AlipayOpenAppQrcodeCreateModel model = new AlipayOpenAppQrcodeCreateModel();
        model.setUrlParam(urlParam);
        model.setQueryParam(Strings.isBlank(queryParam) ? "describe=" + describe : queryParam);
        model.setDescribe(describe);
        model.setSize(size); // (s - 8cm, m - 12cm, l - 30cm)
        request.setBizModel(model);
        log.info("生成支付宝小程序二维码请求参数：{}", Jsons.toJsonString(request));
        try {
            AlipayOpenAppQrcodeCreateResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                return response;
            } else {
                throw Ex.business(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
    }


    /**
     * ant.merchant.expand.indirect.image.upload(图片上传)
     */

    public String antMerchantExpandIndirectImageUpload(String imageUrl) {
        String imageBase64 = Base64Util.GetImageStrFromUrl(imageUrl);
        AntMerchantExpandIndirectImageUploadRequest request = new AntMerchantExpandIndirectImageUploadRequest();
        request.setImageType("jpg");
        FileItem imageContent = new FileItem("imageContent.jpg", Base64.getDecoder().decode(imageBase64));
        request.setImageContent(imageContent);
        AntMerchantExpandIndirectImageUploadResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            throw Ex.business(response.getSubMsg());
        }
        return response.getImageId();
    }

    /**
     * alipay.user.agreement.page.sign(支付宝个人协议页面签约接口)
     */
    public String alipayUserAgreementPageSign(String externalAgreementNo) {
        AlipayUserAgreementPageSignRequest request = new AlipayUserAgreementPageSignRequest();
        AlipayUserAgreementPageSignModel model = new AlipayUserAgreementPageSignModel();
        model.setPersonalProductCode("GENERAL_WITHHOLDING_P");
        model.setSignScene("INDUSTRY|DEFAULT_SCENE");
        model.setExternalAgreementNo(externalAgreementNo);
        // 设置请按当前接入的方式进行填充
        AccessParams accessParams = new AccessParams();
        accessParams.setChannel("ALIPAYAPP");
        model.setAccessParams(accessParams);
//        model.setProductCode("GENERAL_WITHHOLDING");
        request.setBizModel(model);
        if (DevOption.isDevModel()) {
            request.setNotifyUrl(testNotifyUrl);
        } else {
            request.setNotifyUrl(notifyUrl);
        }

        String signStr = "";
        try {
//            AlipayUserAgreementPageSignResponse response = alipayClient.pageExecute(request, "GET");
            AlipayUserAgreementPageSignResponse response = alipayClient.sdkExecute(request);
            log.info("调用支付宝个人协议页面签约接口, 响应数据: {}", Jsons.toFormatJsonString(response));

            signStr = URLEncoder.encode(response.getBody(), "UTF-8");

//            signStr = response.getBody();
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        } catch (UnsupportedEncodingException e) {
            throw Ex.business(e.getMessage());
        }
        log.info("调用支付宝个人协议页面签约接口, 请求数据: {}", Jsons.toFormatJsonString(request.getBizModel()));
        log.info("调用支付宝个人协议页面签约接口, 响应数据: {}", signStr);
        return signStr;
    }

    /**
     * alipay.user.agreement.unsign(支付宝个人协议解约接口)
     */
    public void alipayUserAgreementUnsign(String agreementNo) {
        AlipayUserAgreementUnsignRequest request = new AlipayUserAgreementUnsignRequest();
        AlipayUserAgreementUnsignModel model = new AlipayUserAgreementUnsignModel();
        model.setAgreementNo(agreementNo);
        request.setBizModel(model);
        AlipayUserAgreementUnsignResponse response = null;
        try {
            response = alipayClient.execute(request);
            if (!Objects.equals(response.getCode(), "10000")) {
                throw Ex.business(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        log.info("调用支付宝个人协议解约接口, 请求数据: {}", Jsons.toFormatJsonString(request.getBizModel()));
        log.info("调用支付宝个人协议解约接口, 响应数据: {}", Jsons.toFormatJsonString(response));
    }

    /**
     * alipay.user.agreement.query(支付宝个人代扣协议查询接口)
     */
    public String alipayUserAgreementQuery(String agreementNo) {
        AlipayUserAgreementQueryRequest request = new AlipayUserAgreementQueryRequest();
        AlipayUserAgreementQueryModel model = new AlipayUserAgreementQueryModel();
        model.setExternalAgreementNo(agreementNo);

        try {
            AlipayUserAgreementQueryResponse response = alipayClient.execute(request);
            if (!Objects.equals(response.getCode(), "10000")) {
                throw Ex.business(response.getSubMsg());
            }
            return response.getMsg();
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }

    }

    /**
     * alipay.fund.trans.app.pay(现金红包无线支付接口)
     */
    public String alipayFundTransAppPay(String outBizNo, String amount, String orderId) {
        AlipayFundTransAppPayRequest request = new AlipayFundTransAppPayRequest();
        AlipayFundTransAppPayModel model = new AlipayFundTransAppPayModel();
        model.setOutBizNo(outBizNo);
        model.setTransAmount(amount);
        model.setOrderId(orderId);
        model.setProductCode("TRUSTEESHIP_WALLET");
        model.setBizScene("DEPOSIT");
        log.info("用户充值创建订单:{}", Jsons.toFormatJsonString(model));
        request.setBizModel(model);
        try {
            AlipayFundTransAppPayResponse response = alipayClient.sdkExecute(request);
            log.info("现金红包无线支付接口:{}", Jsons.toJsonString(response));
            return response.getBody();
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
    }
    /**
     * 用户充值创建订单 alipay.fund.wallet.depositorder.create
     */
    public String alipayFundWalletDepositOrderCreate(String outBizNo, String amount, String userWalletId) {
        AlipayFundWalletDepositorderCreateRequest request = new AlipayFundWalletDepositorderCreateRequest();
        AlipayFundWalletDepositorderCreateModel model = new AlipayFundWalletDepositorderCreateModel();
        model.setOutBizNo(outBizNo);
        model.setAmount(amount);
        model.setProductCode(FUND_TRUSTSHIP);
        model.setBizScene(STANDARD_SCENE_WALLET);
        model.setUserWalletId(userWalletId);
        model.setOrderTitle("回收专款充值");
        model.setTimeExpire(Dates.addHours(Dates.getTimeNow(), 1));
        request.setBizModel(model);
        log.info("用户充值创建订单:{}", Jsons.toFormatJsonString(model));

        try {
            AlipayFundWalletDepositorderCreateResponse response = alipayClient.execute(request);
            log.info("用户充值创建订单:{}", Jsons.toFormatJsonString(response));
            if (!Objects.equals(response.getCode(), "10000")) {
                throw Ex.business(response.getSubMsg());
            }
            return response.getFundOrderId();
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
    }

    /**
     * alipay.open.file.upload(支付宝文件上传接口)
     */
    public String alipayOpenFileUpload(String imageUrl) {
        final String imageBase64 = Base64Util.GetImageStrFromUrl(imageUrl);
        AlipayOpenFileUploadRequest request = new AlipayOpenFileUploadRequest();
        FileItem imageContent = new FileItem("imageContent.jpg", Base64.getDecoder().decode(imageBase64));
        request.setFileContent(imageContent);
        request.setBizCode("content_creation");
        AlipayOpenFileUploadResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            if (!response.isSuccess()) {
                throw Ex.business(response.getSubMsg());
            }
            return response.getFileId();
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
    }

    /**
     * ant.merchant.expand.shop.create(蚂蚁店铺创建)
     * https://opendocs.alipay.com/open/05afbc4a_ant.merchant.expand.shop.create?scene=common&pathHash=bf443b73
     */
    public AntMerchantExpandShopCreateResponse antMerchantExpandShopCreate(AntMerchantExpandShopCreateModel model) {
        // 构造请求参数以调用接口
        AntMerchantExpandShopCreateRequest request = new AntMerchantExpandShopCreateRequest();
        request.setBizModel(model);
        AntMerchantExpandShopCreateResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }

        log.info("调用蚂蚁店铺创建接口, 响应数据: {}", Jsons.toFormatJsonString(response));
        return response;

    }

    /**
     * 修改蚂蚁店铺信息
     */
    public AntMerchantExpandShopModifyResponse antMerchantExpandShopModify(AntMerchantExpandShopModifyModel model) {
        // 构造请求参数以调用接口
        AntMerchantExpandShopModifyRequest request = new AntMerchantExpandShopModifyRequest();
        request.setBizModel(model);
        AntMerchantExpandShopModifyResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }

        log.info("调用蚂蚁店铺修改接口, 响应数据: {}", Jsons.toFormatJsonString(response));
        return response;
    }

    /**
     * 二级回收商代扣关系维护	alipay.commerce.recycle.deduct.relation.save
     * handle_type	String	操作类型：
     * 关系绑定:BIND
     * 关系解绑:UNBIND	BIND
     * second_merchant_pid	String	二级回收商的支付宝pid	2088601249230414
     * bind_wallet_type	String	二级回收商的出资钱包类型
     * 余额：BALANCE
     * 场景钱包：WALLET	BALANCE
     * bind_wallet_id	String	二级回收商的出资钱包ID	2088601249230414
     */
    public AlipayCommerceRecycleDeductRelationSaveResponse alipayCommerceRecycleDeductRelationSave(AlipayCommerceRecycleDeductRelationSaveModel model) {
        AlipayCommerceRecycleDeductRelationSaveRequest request = new AlipayCommerceRecycleDeductRelationSaveRequest();

        request.setBizModel(model);
        AlipayCommerceRecycleDeductRelationSaveResponse response = null;
        try {
            response = alipayClient.execute(request);
            if (!response.isSuccess()) {
                throw Ex.business(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 维护回收平台下游分账关系（批量）
     * 接口英文名称：alipay.commerce.recycle.royalty.relation.save
     * 接口类型：OPENAPI
     * 使用说明：
     * ● 此接口可以绑定/解绑
     * ● 回收平台也需要将自己作为分账下游进行分账关系的绑定，绑定主体=回收平台，绑定下游=回收平台
     * handle_type	String	操作类型：
     * 关系绑定:BIND
     * 关系解绑:UNBIND	BIND
     * relation_list	List
     * bind_role_type	String	绑定的分账下游角色类型
     * 蚂蚁门店:SHOP
     * 回收平台:MERCHANT
     * bind_role_id	String	绑定的分账下游角色id
     * 蚂蚁门店: shopid
     * 回收平台：pid
     * bind_wallet_type	String	分账账户类型，当前只支持分账到余额
     * 余额：BALANCE	BALANCE
     * bind_wallet_id	String	分账用户余额户id，即userId	2088601249230414
     */
    public AlipayCommerceRecycleRoyaltyRelationSaveResponse alipayCommerceRecycleRoyaltyRelationSave(AlipayCommerceRecycleRoyaltyRelationSaveModel model) {
        AlipayCommerceRecycleRoyaltyRelationSaveRequest request = new AlipayCommerceRecycleRoyaltyRelationSaveRequest();
        request.setBizModel(model);
        AlipayCommerceRecycleRoyaltyRelationSaveResponse response = null;
        try {
            response = alipayClient.execute(request);
            log.info("维护回收平台下游分账关系（批量）:{}", Jsons.toFormatJsonString(response));
            if (!response.isSuccess()) {
                throw Ex.business(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 查询回收平台绑定的代扣关系
     * 接口英文名称：alipay.commerce.recycle.deduct.relation.query
     * second_merchant_pid	String	二级回收商pid，与openid二选一
     * second_merchant_open_id	String	二级回收商openid
     */
    public AlipayCommerceRecycleDeductRelationQueryResponse alipayCommerceRecycleDeductRelationQuery(AlipayCommerceRecycleDeductRelationQueryModel model) {
        AlipayCommerceRecycleDeductRelationQueryRequest request = new AlipayCommerceRecycleDeductRelationQueryRequest();
        request.setBizModel(model);
        AlipayCommerceRecycleDeductRelationQueryResponse response = null;
        try {
            response = alipayClient.execute(request);
            if (!response.isSuccess()) {
                throw Ex.business(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 查询回收平台绑定的分账关系(批量)
     * 接口英文名称：alipay.commerce.recycle.royalty.relation.quer
     * bind_role_type	String	绑定角色	MERCHANT SHOP
     * bind_role_ids	String[]	绑定对象	门店ID或则回收平台分账主体
     */
    public AlipayCommerceRecycleRoyaltyRelationQueryResponse alipayCommerceRecycleRoyaltyRelationQuery(AlipayCommerceRecycleRoyaltyRelationQueryModel model) {
        AlipayCommerceRecycleRoyaltyRelationQueryRequest request = new AlipayCommerceRecycleRoyaltyRelationQueryRequest();
        request.setBizModel(model);
        AlipayCommerceRecycleRoyaltyRelationQueryResponse response = null;
        try {
            response = alipayClient.execute(request);
            if (!response.isSuccess()) {
                throw Ex.business(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 创建回收订单 alipay.open.mini.order.create
     * https://opendocs.alipay.com/mini/54f80876_alipay.open.mini.order.create?scene=common&pathHash=b9743ab7
     */

    public AlipayOpenMiniOrderCreateResponse alipayOpenMiniOrderCreate(AlipayOpenMiniOrderCreateModel model) {
        log.info("创建回收订单参数:{}", this.serverUrl);
        log.info("创建回收订单参数:{}", Jsons.toFormatJsonString(alipayClient));
        AlipayOpenMiniOrderCreateRequest request = new AlipayOpenMiniOrderCreateRequest();
        request.setBizModel(model);
        AlipayOpenMiniOrderCreateResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("创建回收订单 :{}", Jsons.toFormatJsonString(response));
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 修改订单   alipay.open.mini.order.modify
     * https://opendocs.alipay.com/mini/5440e982_alipay.open.mini.order.modify?scene=common&pathHash=90bccf0a
     */
    public AlipayOpenMiniOrderModifyResponse alipayOpenMiniOrderModify(AlipayOpenMiniOrderModifyModel model) {
        AlipayOpenMiniOrderModifyRequest request = new AlipayOpenMiniOrderModifyRequest();
        request.setBizModel(model);
        AlipayOpenMiniOrderModifyResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("修改订单 :{}", Jsons.toFormatJsonString(response));
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 商家修改上门时间
     * alipay.open.mini.order.delivery.modify
     */
    public AlipayOpenMiniOrderDeliveryModifyResponse alipayOpenMiniOrderDeliveryModify(AlipayOpenMiniOrderDeliveryModifyModel model) {
        AlipayOpenMiniOrderDeliveryModifyRequest request = new AlipayOpenMiniOrderDeliveryModifyRequest();
        request.setBizModel(model);
        AlipayOpenMiniOrderDeliveryModifyResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("商家修改订单 :{}", Jsons.toFormatJsonString(response));
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 订单发货
     * alipay.open.mini.order.delivery.send
     */
    public AlipayOpenMiniOrderDeliverySendResponse alipayOpenMiniOrderDeliverySend(AlipayOpenMiniOrderDeliverySendModel model) {
        AlipayOpenMiniOrderDeliverySendRequest request = new AlipayOpenMiniOrderDeliverySendRequest();
        request.setBizModel(model);
        AlipayOpenMiniOrderDeliverySendResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("订单发货 :{}", Jsons.toFormatJsonString(response));
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 订单确认收货（快递上门方式）
     * alipay.open.mini.order.delivery.receive
     */
    public AlipayOpenMiniOrderDeliveryReceiveResponse alipayOpenMiniOrderDeliveryReceive(AlipayOpenMiniOrderDeliveryReceiveModel model) {
        AlipayOpenMiniOrderDeliveryReceiveRequest request = new AlipayOpenMiniOrderDeliveryReceiveRequest();
        request.setBizModel(model);
        log.info("====================>订单确认收货{}",Jsons.toFormatJsonString(model));
        AlipayOpenMiniOrderDeliveryReceiveResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("订单确认收货（快递上门方式） :{}", Jsons.toFormatJsonString(response));
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 查询回收订单信息 alipay.open.mini.order.query
     */
    public AlipayOpenMiniOrderQueryResponse alipayOpenMiniOrderQuery(AlipayOpenMiniOrderQueryModel model) {
        AlipayOpenMiniOrderQueryRequest request = new AlipayOpenMiniOrderQueryRequest();
        request.setBizModel(model);
        AlipayOpenMiniOrderQueryResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
//            log.info("查询回收订单信息 :{}", Jsons.toFormatJsonString(response));
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 同步售后结果（快递上门方式商户寄回）  alipay.open.mini.order.aftersale.sync
     */
    public AlipayOpenMiniOrderAftersaleSyncResponse alipayOpenMiniOrderAftersaleSync(AlipayOpenMiniOrderAftersaleSyncModel model) {
        AlipayOpenMiniOrderAftersaleSyncRequest request = new AlipayOpenMiniOrderAftersaleSyncRequest();
        request.setBizModel(model);
        AlipayOpenMiniOrderAftersaleSyncResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("同步售后结果（快递上门方式商户寄回） :{}", Jsons.toFormatJsonString(response));
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 查询售后单信息 alipay.open.mini.order.aftersale.query
     */

    public AlipayOpenMiniOrderAftersaleQueryResponse alipayOpenMiniOrderAftersaleQuery(AlipayOpenMiniOrderAftersaleQueryModel model) {
        AlipayOpenMiniOrderAftersaleQueryRequest request = new AlipayOpenMiniOrderAftersaleQueryRequest();
        request.setBizModel(model);
        AlipayOpenMiniOrderAftersaleQueryResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("查询售后单信息 :{}", Jsons.toFormatJsonString(response));
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 取消订单
     *
     * @param alipayOpenMiniOrderCloseModel
     */

    public void alipayOpenMiniOrderClose(AlipayOpenMiniOrderCloseModel alipayOpenMiniOrderCloseModel) {
        AlipayOpenMiniOrderCloseRequest request = new AlipayOpenMiniOrderCloseRequest();
        request.setBizModel(alipayOpenMiniOrderCloseModel);
        AlipayOpenMiniOrderCloseResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("关闭订单 :{}", Jsons.toFormatJsonString(response));
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
    }

    /**
     * 支付宝交易创建接口
     *
     * @param appId
     * @param openId
     * @param orderNo
     * @param totalAmount
     * @param subject
     * @param goodsList
     * @return
     */

    public String alipayTradeCreate(String appId, String openId, String orderNo, String totalAmount, String subject, List<GoodsDetail> goodsList) {
        return "";
    }

    /**
     * 上传回收报告
     *
     * @param model
     */
    public void alipayCommerceRecycleQcreportUpload(AlipayCommerceRecycleQcreportUploadModel model) {
    }

    public AlipayTradePayResponse walletAlipayTradePay(String smId, String outTradeNo, BigDecimal amount, String agreementNo) {
        AlipayTradePayRequest request = new AlipayTradePayRequest();
        JSONObject extendParamsMap = new JSONObject();
        //判断测试环境
        if (DevOption.isDevModel()) {
            request.setNotifyUrl(testNotifyUrl);
        } else {
            request.setNotifyUrl(notifyUrl);
        }
        JSONObject agreementParams = new JSONObject();
        JSONObject bizContent = new JSONObject();
        JSONObject subMerchant = new JSONObject();
        JSONObject settleInfo = new JSONObject();
        List<JSONObject> settleDetailInfos = new ArrayList<>();
        JSONObject settleDetailInfo = new JSONObject();
        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("total_amount", amount.toString());
        bizContent.put("product_code", "GENERAL_WITHHOLDING");
        bizContent.put("subject", "交易支付扣款");
        bizContent.put("is_async_pay", false);
        subMerchant.put("merchant_id", "2088160320226091");
        subMerchant.put("merchant_type", "alipay");
        settleInfo.put("settle_period_time", "1d");
        settleDetailInfo.put("amount", amount.toString());
        settleDetailInfo.put("trans_in_type", "defaultSettle");
        settleDetailInfos.add(settleDetailInfo);
        settleInfo.put("settle_detail_infos", settleDetailInfos);
        agreementParams.put("agreement_no", agreementNo);
        extendParamsMap.put("activity", "{\"PCARD_APPOINT_ASSET_CONSULT\":\"{\\\"bizCode\\\":\\\"STANDARD_SCENE_WALLET\\\",\\\"bizId\\\":\\\"2024101866209201180000121635\\\"}\"}");
        extendParamsMap.put("enable_pay_channels", "platformCard");
        extendParamsMap.put("settle_mode", "CAPTURE");
        bizContent.put("agreement_params", agreementParams);
        bizContent.put("extend_params", extendParamsMap);
        bizContent.put("sub_merchant", subMerchant);
        bizContent.put("settle_info", settleInfo);
        request.setBizContent(bizContent.toJSONString());
        log.info("支付宝扣款请求参数：{}", Jsons.toFormatJsonString(bizContent));
        AlipayTradePayResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            if (!response.isSuccess()) {
                throw Ex.business("支付宝扣款异常, " + response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business("支付宝扣款异常", e);
//            log.error("支付宝扣款接口异常  {}", e);
        }
        return response;
    }

    /**
     * alipay.commerce.recycle.order.pre.check 订单确认预校验
     */
    public AlipayCommerceRecycleOrderPreCheckResponse alipayCommerceRecycleOrderPreCheck(AlipayCommerceRecycleOrderPreCheckModel model) {
        AlipayCommerceRecycleOrderPreCheckRequest request = new AlipayCommerceRecycleOrderPreCheckRequest();
        request.setBizModel(model);
        AlipayCommerceRecycleOrderPreCheckResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("订单确认预校验 :{}", Jsons.toFormatJsonString(response));
            if (!response.isSuccess()) {
                throw Ex.business(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    public void alipayCommerceRecycleOrderMerchantConfirm(AlipayCommerceRecycleOrderMerchantConfirmModel model) {
        AlipayCommerceRecycleOrderMerchantConfirmRequest request = new AlipayCommerceRecycleOrderMerchantConfirmRequest();
        request.setBizModel(model);
        AlipayCommerceRecycleOrderMerchantConfirmResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("订单确认质检结果:{}", Jsons.toFormatJsonString(response));
            if (!response.isSuccess()) {
                throw Ex.business(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
    }

    public AlipayCommerceRecycleInstshopQrcodeConsultResponse alipayCommerceRecycleInstshopQrcodeConsult(String alipayShopId) {

        // 构造请求参数以调用接口
        AlipayCommerceRecycleInstshopQrcodeConsultRequest request = new AlipayCommerceRecycleInstshopQrcodeConsultRequest();
        AlipayCommerceRecycleInstshopQrcodeConsultModel model = new AlipayCommerceRecycleInstshopQrcodeConsultModel();
        // 设置回收商唯一服务编码,预发：SZDZXH_OFFLINE_PRE ,生产：SZDZXH_OFFLINEDevOption.isDevModel() ? "SZDZXH_OFFLINE_PRE" :
        model.setServiceCode( "SZDZXH_OFFLINE");
        // 设置蚂蚁门店ID
        model.setAlipayShopId(alipayShopId);
        request.setBizModel(model);
        AlipayCommerceRecycleInstshopQrcodeConsultResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            log.info("生成门店二维码结果:{}", Jsons.toFormatJsonString(response));
            if (!response.isSuccess()) {
                throw Ex.business(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw Ex.business(e.getMessage());
        }
        return response;
    }

    /**
     * 门店已发货
     * 接口英文名称：alipay.open.mini.order.delivery.send
     * order_id	String	支付宝回收订单号；order_id和out_order_id二选一	2015042321001004720200028594
     * out_order_id	String	商户订单号，创建订单请求由商户传入；order_id和out_order_id二选一
     * user_id	String	用户2088	2088***
     * finish_all_delivery	String	0：已下物流单
     * 1：快递小哥已取件	1
     * ship_done_time	String	取件时间	2023-04-27 10:05:00
     * delivery_list	List<DeliveryInfoDTO>	物流信息
     * delivery_id	String	物流公司	SF
     * waybill_id	String	物流单号	2343455
     * item_info_list	List<GoodsItemDTO>	回收产品信息
     * goods_id	String	商家侧回收spuid
     * out_item_id	String	商家侧回收skuid
     * out_sku_id	String	商家侧回收skuid
     * item_cnt	String	回收产品数量	1
     */

    /**
     * 小程序发送模板消息
     * 接口英文名称：alipay.open.app.mini.templatemessage.send
     * 接口描述：小程序通过openapi向用户发送模板消息
     * 接口功能：小程序可以通过该接口向用户发送模板消息，用于订单状态变更、活动通知等场景
     * 接口链接：https://opendocs.alipay.com/mini/6430ce5a_alipay.open.app.mini.templatemessage.send
     *
     * @return AlipayOpenAppMiniTemplatemessageSendResponse
     */
    public AlipayOpenAppMiniTemplatemessageSendResponse alipayOpenAppMiniTemplateMessageSend(AlipayOpenAppMiniTemplatemessageSendModel model) {
        
        AlipayOpenAppMiniTemplatemessageSendRequest request = new AlipayOpenAppMiniTemplatemessageSendRequest();
        request.setBizModel(model);
        
        log.info("小程序发送模板消息请求参数：{}", Jsons.toJsonString(request));
        
        AlipayOpenAppMiniTemplatemessageSendResponse response = null;
        try {
            if (Strings.isNotBlank(this.publicKey)) {
                response = alipayClient.execute(request);
            } else {
                response = alipayClient.certificateExecute(request);
            }
            
            log.info("小程序发送模板消息结果：{}", Jsons.toJsonString(response));
            
            if (!response.isSuccess()) {
                log.error("小程序发送模板消息失败：{}", response.getSubMsg());
                throw Ex.business("小程序发送模板消息异常：" + response.getSubMsg());
            }
            
        } catch (AlipayApiException e) {
            log.error("小程序发送模板消息接口异常：{}", e.getMessage());
            throw Ex.business("小程序发送模板消息接口异常：" + e.getMessage());
        }
        
        return response;
    }


}
